/************************************************************************
This file is part of lpc2xxx package for the simpleRTJ virtual machine.

This file is covered by the GNU GPL with the following exception:
  As a special exception, the copyright holders of this library give you permission
  to link this library with independent modules to produce an executable, regardless
  of the license terms of these independent modules, and to copy and distribute the
  resulting executable under terms of your choice, provided that you also meet, for
  each linked independent module, the terms and conditions of the license of that
  module. An independent module is a module which is not derived from or based on
  this library. If you modify this library, you may extend this exception to your
  version of the library, but you are not obligated to do so. If you do not wish
  to do so, delete this exception statement from your version.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright (c) 2000-2006 RTJ Computing Pty. Ltd. All rights reserved.
***********************************************************************/
package lpc2xxx.hw;


/**
 * Class providing access to 6 analog inputs that are available on the LPC214x.<br>
 * The following ADC channels are available on LPC214x devices:<br>
 * <code>
 * AD0.1 - GPIO pin P0.28<br>
 * AD0.2 - GPIO pin P0.29<br>
 * AD0.3 - GPIO pin P0.30<br>
 * AD0.4 - GPIO pin P0.25<br>
 * AD0.6 - GPIO pin P0.4<br>
 * AD0.7 - GPIO pin P0.5<br>
 * </code>
 * <p>
 * Add your own code (if required) to implement advanced features and/or additional 8 channels 
 * that are available on LPC2148.
 */
public class ADC
{
    /** Analog channel 1 (P0.28) */
    public final static int A1 = 1;
    /** Analog channel 2 (P0.29) */
    public final static int A2 = 2;
    /** Analog channel 3 (P0.30) */
    public final static int A3 = 3;
    /** Analog channel 4 (P0.25) */
    public final static int A4 = 4;
    /** Analog channel 6 (P0.4) */
    public final static int A6 = 6;
    /** Analog channel 7 (P0.5) */
    public final static int A7 = 7;

    /** Indicates whether the ADC was initialized */
    private static boolean initialized = false;
    /** Analog channel */
    private int ad;

    /**
     * ADC object constructor. Creates an instance of ADC class with the 
     * specified analog channel.<br>
     * @param ad analog channel, use provided An constants.
     */
    public ADC(int ad)
    {
        this.ad = ad;
        if (!initialized)
        {
            initialized = true;
            init();
        }

        if ((ad & A1) == A1)
            GPIO.config(1, 0xFCFFFFFF, 0x01000000);
        if ((ad & A2) == A2)
            GPIO.config(1, 0xF3FFFFFF, 0x04000000);
        if ((ad & A3) == A3)
            GPIO.config(1, 0xCFFFFFFF, 0x10000000);
        if ((ad & A4) == A4)
            GPIO.config(1, 0xFFF3FFFF, 0x00040000);
        if ((ad & A6) == A6)
            GPIO.config(0, 0xFFFFFCFF, 0x00000300);
        if ((ad & A7) == A7)
            GPIO.config(0, 0xFFFFF3FF, 0x00000C00);
    }

    /**
     * Starts the conversion on the specified analog channel and returns 
     * the 10-bit value.
     * @return 10-bit value of the specified analog input
     */
    public int get()
    {
        return get(ad);
    }

    /**
     * Starts the conversion on the specified analog channel and returns 
     * the millivolt value.
     * @return millivolt value of the specified analog input
     */
    public int getmV()
    {
        return getmV(ad);
    }

    /** Initializes ADC hardware */
    private static native void init();
    /** Reads the analog value on specified channel */
    private static native int get(int ad);
    /** Reads the analog value on specified channel and returns it as mV */
    private static native int getmV(int ad);
}
